package org.grottarossa.ui.core.casemanagement.bpm;

import java.util.ArrayList;

import org.grottarossa.template.data.pojo.workflows.Activity;
import org.grottarossa.template.data.pojo.workflows.Dispatch;
import org.grottarossa.template.data.pojo.workflows.WorkItem;
import org.grottarossa.template.data.pojo.workflows.Workflow;
import org.grottarossa.template.drivers.components.tokens.CaseManagementId;
import org.grottarossa.template.drivers.components.tokens.DocumentManagementId;
import org.grottarossa.ui.core.ApplicationSession;
import org.grottarossa.ui.core.base.BasePanel;
import org.grottarossa.ui.core.base.IBaseComponent;
import org.grottarossa.ui.core.casemanagement.CaseManagementPanel;
import org.grottarossa.ui.core.casemanagement.FileStoreManagementPanel;
import org.grottarossa.ui.core.casemanagement.bpm.actionsbar.LockBar;
import org.grottarossa.ui.core.casemanagement.bpm.actionsbar.LockBarFactory;
import org.grottarossa.ui.core.layout.EmptyPanel;
import org.grottarossa.ui.core.layout.LayoutFactory;


import com.vaadin.terminal.Sizeable;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Panel;
import com.vaadin.ui.VerticalLayout;

/***
 * Pannello che si occupa della parte di buisness process management
 * @author 
 *
 */
public class BaseBPMPanel extends BasePanel
{
	private static final long serialVersionUID = -6727286334538896706L;

	/**La lista contiene i dispatch button associati all'attivita' specifica di processo.*/
	private ArrayList< BPMDispatchButton > m_buttons = null;

	/**Su questo layout vengono inseriti i dispatch button.*/
	private HorizontalLayout m_dispatchButtonsBar = null;

	/*** Layout del pannello ***/
	private VerticalLayout m_layout;

	/**Rappresenta il listener su cui sono definite le action dei pulsanti di dispatch.*/
	private BPMDispatchListener listener = null;

	/**Rappresenta l'istanza di processo attiva.*/
	private WorkItem m_workItem = null;

	/**Rappresenta l'attivita' di processo in cui effettivamente mi trovo.*/
	private Activity m_activity = null;

	private IBaseComponent m_view = null;

	/**Lista delle azioni da eseguire al termine del processo*/
	private ArrayList<IAction> m_onCloseActions;

	private Workflow m_workflow;

	/**Costruttore vuoto*/
	public BaseBPMPanel(ApplicationSession appSession)
	{
		super(appSession, null);
		initializeComponents();
	}

	/**
	 * Il costruttore genera il pannello.
	 *
	 * @param workItem Rappresenta l'istanza di processo attiva.
	 * @param activity Rappresenta l'attivita' di processo in cui effettivamente mi trovo.
	 *
	 * */
	public BaseBPMPanel(ApplicationSession appSession, WorkItem workItem, Activity activity, Workflow workflow)
	throws Exception
	{
		super(appSession, null);
		initStatusMembers(workItem, activity, null, workflow, null);
		initializeComponents();
		drawPanel();
		addLockAndSuspendToButtonsBar(m_dispatchButtonsBar, m_workItem, m_workflow);
	}

	public BaseBPMPanel(ApplicationSession appSession, WorkItem workItem, Activity activity, IBaseComponent view, Workflow workflow)
	throws Exception
	{
		super(appSession, null);
		initStatusMembers(workItem, activity, null, workflow, view);
		initializeComponents();
		drawPanel();
		addLockAndSuspendToButtonsBar(m_dispatchButtonsBar, m_workItem, m_workflow);
	}

	public BaseBPMPanel(ApplicationSession appSession, WorkItem workItem, Activity activity,
			IBaseComponent view, ArrayList<IAction> onCloseActions, Workflow workflow)
	throws Exception
	{
		super(appSession, null);
		initStatusMembers(workItem, activity, onCloseActions, workflow, view);
		initializeComponents();
		drawPanel();
		addLockAndSuspendToButtonsBar(m_dispatchButtonsBar, m_workItem, m_workflow);
	}

	@Override
	protected void initializeComponents()
	{
		//Imposto il layout del pannello
		m_layout = new VerticalLayout();
		m_layout.setWidth(100, Sizeable.UNITS_PERCENTAGE);
		m_layout.setHeight(100, Sizeable.UNITS_PERCENTAGE);
		setLayout(m_layout);

		//genero la dispatch buttons bar
		this.m_dispatchButtonsBar = new HorizontalLayout();
		this.m_buttons = new ArrayList<BPMDispatchButton>();

		if(m_activity != null)
			for(Dispatch dispatch: m_activity.getDispatchs() )
			{
				BPMDispatchButton button = new BPMDispatchButton(dispatch.getDisplay());
				listener = new BPMDispatchListener(m_appSession, m_workItem, dispatch, this, m_onCloseActions);

				button.addListener(listener);
				m_buttons.add(button);
				m_dispatchButtonsBar.addComponent(button);
			}


	}

	/***
	 * Inizializza le variabili di stato
	 * @param workItem
	 * @param activity
	 * @param onCloseActions
	 * @param workflow
	 * @param view
	 */
	private void initStatusMembers(WorkItem workItem, Activity activity, ArrayList<IAction> onCloseActions, Workflow workflow, IBaseComponent view)
	{
		this.m_workItem = workItem;
		this.m_activity = activity;
		this.m_onCloseActions = onCloseActions;
		this.m_workflow = workflow;
		this.m_view = view;
	}

	/***
	 * Disegna il pannello in base allo stato
	 * @throws Exception
	 */
	private void drawPanel() throws Exception
	{
		//nome del layout
		String layoutName = m_activity.getActivityLayout();

		Component workflowPanel = null;

		//se l'istanza di processo e' legata ad un caseFolder carico il layout dal layout manager
		if(m_workItem.getWorkItemType().isCaseFolder())
			workflowPanel = new CaseManagementPanel(m_appSession, (CaseManagementId)m_workItem.getObjectId(), m_dispatchButtonsBar, layoutName, m_view);
		else if(m_workItem.getWorkItemType().isFileStore())
		{
			DocumentManagementId id = (DocumentManagementId)m_workItem.getObjectId();
			workflowPanel = new FileStoreManagementPanel(m_appSession, id, m_dispatchButtonsBar, layoutName);
		}
		else if(m_workItem.getWorkItemType().isProcess())
			workflowPanel = new ProcessManagementPanel(m_appSession, layoutName, m_dispatchButtonsBar);
		else
			workflowPanel = new EmptyPanel("Process", layoutName);

		workflowPanel.setHeight(100, Sizeable.UNITS_PERCENTAGE);
		workflowPanel.setWidth(100, Sizeable.UNITS_PERCENTAGE);
		m_layout.addComponent(workflowPanel);
		m_layout.setComponentAlignment(workflowPanel, Alignment.TOP_LEFT);


	}

	/***
	 * Aggiunge i pulsanti di lock, assignto e suspend ad una barra
	 * @param buttonsBar Barra sulla quale aggiungere i pulsanti
	 * @param workItem
	 * @param workflow
	 */
	private void addLockAndSuspendToButtonsBar(HorizontalLayout buttonsBar, WorkItem workItem, Workflow workflow)
	{
		LockBarFactory f = new LockBarFactory(m_appSession);
		LockBar lb = f.createLockBar(workflow, workItem, m_view);
		ArrayList<Button> buttons = lb.getButtons();

		for(Button b : buttons)
			buttonsBar.addComponent(b);
	}

	/**
	 * La funzione effettua il reload del pannello.
	 *
	 * @param workItem Rappresenta l'istanza di processo attiva.
	 * @param activity Rappresenta l'attivita' di processo in cui effettivamente mi trovo.
	 *
	 * */
	public void reload(WorkItem workItem, Activity activity, Workflow workflow) throws Exception
	{
		removeAllComponents();
		initStatusMembers(workItem, activity, m_onCloseActions, workflow, m_view);
		drawPanel();
	}
}
